﻿/* Copyright (C) 2013 GruntXProductions
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */


using System;
using System.Collections.Generic;
using System.Text;
using Sys = Cosmos.System;

namespace GDOS
{
    public class Kernel : Sys.Kernel
    {
        public static string CurrentDirectory = "A:\\";
        public static VirtualFileSystem FileSystem;
        private static List<Command> commands = new List<Command>();
        
        protected override void BeforeRun()
        {
            Console.WriteLine("GLNFS Filesystem. (c) GruntXProductions 2012-2013");
            Console.WriteLine("Starting G-DOS...");
            // Lets add all of the commands we want to use to the list
            commands.Add(new Commands.Dir());
            commands.Add(new Commands.Fdisk());
            commands.Add(new Commands.Format());
            commands.Add(new Commands.Format());
            commands.Add(new Commands.CD());
            commands.Add(new Commands.Mkdir());

            GruntyOS.HAL.ATA.Detect(); // This will detect all ATA devices and add them to the device filesystem
            FileSystem = new VirtualFileSystem(); // We need to make sure VirtualFileSystem is not null
            GruntyOS.CurrentUser.Privilages = 0; // This has to be set, 1 = limited 0 = root
            GruntyOS.CurrentUser.Username = "DOS"; // When using anything under the filenamespace this will be the defualt username
            
            bool usableDriveFound = false; // if no GLNFS partition is detected then we need to do something
            while (!usableDriveFound)
            {
                GruntyOS.HAL.FileSystem.Root = new GruntyOS.HAL.RootFilesystem();
                GruntyOS.HAL.FileSystem.Root.Seperator = '\\'; // Use \ instead of /
                for (int i = 0; i < GruntyOS.HAL.Devices.dev.Count; i++)
                {
                    if (GruntyOS.HAL.Devices.dev[i].dev is Cosmos.Hardware.BlockDevice.Partition)
                    {
                        GruntyOS.HAL.GLNFS FS = new GruntyOS.HAL.GLNFS((Cosmos.Hardware.BlockDevice.Partition)GruntyOS.HAL.Devices.dev[i].dev);

                        usableDriveFound = true;
                        if (GruntyOS.HAL.GLNFS.isGFS((Cosmos.Hardware.BlockDevice.Partition)GruntyOS.HAL.Devices.dev[i].dev))
                        {
                            Console.WriteLine("Drive detected!");
                        }
                        FileSystem.AddDrive(FS);
                    }
                }
                if (!usableDriveFound)
                {
                    Execute("fdisk");
                    Console.WriteLine("Please reboot (and do not forget to format the partition you detected!)");
                    while (true) ;

                }
            }

            GruntyOS.HAL.FileSystem.Root.Mount("\\", FileSystem); // mount the virtual filesystem (We are actually mounting it using Grunty OSes default virtual filesystem)

        }
        
        protected override void Run()
        {
            
            while (true)
            {
                Console.Write(CurrentDirectory + "> ");
                string cmd = Console.ReadLine();
                Execute(cmd);
           
                
            }
        }
        public static void Execute(string cmd)
        {
            Scanner scanner = new Scanner();
            List<object> args = scanner.getTokens(cmd);
            List<string> argsString = new List<string>();

            for (int i = 0; i < args.Count; i++)
            {
                if (args[i] is Scanner.StringLiteral)
                    argsString.Add(((Scanner.StringLiteral)args[i]).Value);
                else
                    argsString.Add(args[i].ToString());
            }
            for (int i = 0; i < commands.Count; i++)
            {
                if (commands[i].Name == argsString[0])
                {
                    commands[i].Execute(argsString.ToArray());
                    break;
                }
            }
        }

    }
}
